关联映射
1. 业务关系分析
在进行多表关联查询之前,需要对表结构的关联关系与业务关系进行分析与理解。
下图以用户,订单,明细,商品表为例分析:
- 用户表与订单表
- 一个用户可以创建多个订单 (一对多)
- 一个订单只能由一个用户创建(一对一)
- 订单表与明细表
- 一个订单可以含有多个订单明细(一对多)
- 一个订单明细只能对应一个订单(一对一)
- 明细表与商品表
- 一个订单明细只能对应一个商品(一对一)
- 一个商品可以被包含在多个订单明细中(一对多)
- 订单表与商品表 (间接关系)
- 一个订单可以拥有多个订单明细,而一个订单明细对应一个商品,即一个订单可以拥有多个商品。
- order -> orderdetail -> items 一对多
- 一个商品可以被包含在多个订单明细中,而一个订单明细对应一个订单,即一个商品可以被包含在多个订单中。
- item -> orderdetail -> order 一对多
- 订单与商品是多对多关系。
- 一个订单可以拥有多个订单明细,而一个订单明细对应一个商品,即一个订单可以拥有多个商品。
- 用户表与商品表 (间接关系)
- 一个用户可以创建多个订单,一个订单可以对应多个订单明细,一个订单明细对应一个商品,即一个用户可以购买多个商品。
- user -> order -> orderdetail -> item 一对多
- 一个商品可以被包含在多个订单明细中,一个订单明细对应一个订单,一个订单对应一个用户,即一个商品可以对应多个用户。
- item -> orderdetail -> order -> user 一对多
- 用户与商品是多对多关系。
- 一个用户可以创建多个订单,一个订单可以对应多个订单明细,一个订单明细对应一个商品,即一个用户可以购买多个商品。
2. 一对一关联查询
在多表查询时,单表的JavaBean不能满足结果集的映射,所以可以使用继承的方法来扩展JavaBean。
|
|
上面的做法与在Orders类中添加一个User类型的属性作用相同。
映射文件配置
|
|
3. 一对多关联查询
一对多查询与一对一查询类似,我们要查询商品以及订单明细则需要在商品类中扩展一个List集合。
|
|
映射文件配置
|
|
4. 多对多关联查询
查询商品以及对应的用户信息。
- 在商品类中添加一个订单明细集合(一个商品对应多个订单明细)
- 在订单明细类中添加一个订单属性(一个订单明细对应一个订单)
- 在订单类中添加一个用户属性(一个订单对应一个用户)
|
|
映射文件配置
|
|
延迟加载
resultMap中的association和collection具有延迟加载的功能。
延迟加载: 先加载主信息,在需要的时候加载关联信息,延迟加载即叫按需加载,也叫懒加载。
1. 设置延迟加载
MyBatis
默认是关闭延迟加载的,需要在配置文件中的标签中手动开启。
settings | description | 验证值组 | 默认值 | |
---|---|---|---|---|
lazyLoadingEnabled | 全局性设置懒加载。 | true | false | true |
aggressiveLazyLoading | 积极性的懒加载,false则是按需加载 | true | false | true |
|
|
2. 在association中使用延迟加载
|
|
查询缓存
1. 一级缓存
一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。
当第一次查询对象1时,将先会去一级缓存中查找是否有对象1的数据信息,如果没有则从数据库中查询到数据信息并构造一个key存储到一级缓存(HashMap)中。
当第二次查询对象1的时候,则可以凭借key在一级缓存中找到数据信息,而不用再去访问数据库。
如果SqlSession进行了事务提交(commit),则会刷新(清空)缓存,目的是为了让缓存存储最新的数据,防止脏读。MyBatis
默认开启一级缓存。
2. 二级缓存
二级缓存是namespace(mapper)级别的缓存,多个SqlSession去操作同一个namespace中的mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
二级缓存存储数据不一定是在内存中,所以需要给缓存的对象实现序列化接口。
二级缓存需要手动设置开启。
开启二级缓存
|
|
MyBatis与Spring整合
由
Spring
维护管理数据源、事务、SqlSessionFactory、mapper。MyBatis
的配置文件只需要配置settings、别名等即可。
|
|